class myJquery {
    //构造函数 通过参数获取指定的元素 并且这些元素放到本对象身上
    constructor(selector) {

        if (typeof selector == "string") {
            if(selector.charAt(0)!="<") {
                let alls = document.querySelectorAll(selector)
                for (let i = 0; i < alls.length; i++) {
                    this[i] = alls[i]
                }
                this.length = alls.length
            }else{
                this[0]=document.createElement(selector.slice(1,-1))
                this.length=1
            }
        }else if(typeof selector=="object"){
            if (selector.length){
                for (let i=0;i<selector.length;i++){
                    this[i]=selector[i]
                }
                this.length=selector.length
            }else{
                this[0]=selector
                this.length=1
            }
        }else if (typeof selector=="function"){
            window.onload=function (){
                selector()
            }
        }
    }
    each(callback) {
        for (let i = 0; i < this.length; i++) {
            callback(i, this[i])
        }
    }
    // css 内容
    css(styleobj) {
        if(typeof styleobj=="object") {
            this.each((index, obj) => {
                for (let i in styleobj) {
                    if (i == "width" || i == "height" || i == "padding" || i == "margin" || i == "marginLeft") {
                        obj.style[i] = parseInt(styleobj[i]) + "px"
                    } else {
                        obj.style[i] = styleobj[i]
                    }
                }

            })
        }else{
            return   parseInt(getComputedStyle(this[0],null)[styleobj] )
        }
        return this
    }
    html(val) {
        if (val) {
            this.each(function (index, obj) {
                obj.innerHTML = val
            })
            return this
        } else {
            let result = []
            this.each(function (index, obj) {
                result.push(obj.innerHTML)
            })
            return result
        }
    }
    animate(attrobj, duration, fn) {
        this.each((index, obj) => {
            let starts = {}
            let changes = {}
            for (let i in attrobj) {
                starts[i] = parseInt(getComputedStyle(obj, null)[i])
                changes[i] = attrobj[i] - starts[i]
            }
            let current = 0
            let times = duration || 1000
            let fn1 = fn || this.linear

            let t = setInterval(function () {
                if (current >= times) {
                    clearInterval(t)
                    for (let i in attrobj) {
                        obj.style[i] = attrobj[i] + "px"
                    }
                } else {

                    for (let i in attrobj) {
                        obj.style[i] = fn1(starts[i], changes[i], current, times) + "px"
                    }
                }

                current += 30
            }, 30)

        })
    }
    click(callback){
        this.each((index,obj)=>{
            obj.onclick= ()=>{
                callback.call(obj)
            }
        })
    }
    slideUp(){

        myJquery.tempheight=this.css("height")
        this.animate({height:0})
    }
    slideDown(){
        if (!myJquery.tempheight){
            myJquery.tempheight=this.css("height")
        }
        this.animate({height:myJquery.tempheight})
        delete myJquery.tempheight
    }
    // 获取所有指定元素的子元素
    getChilds(){
        let arr=[]
        this.each((index,obj)=>{
            arr=arr.concat(this.getChild(obj))
        })

        this.extand(arr,this)
        this.length=arr.length
        return this
    }
    // 获取指定所有元素的父元素
    parents(){
        let alls=new Set()
        this.each((index,obj)=>{
            alls.add(obj.parentNode)
        })
        alls=Array.from(alls)
        this.extand(alls,this)
        this.length=alls.length
        return this
    }
    // 克隆
    clone(type=false){

        this.each((index,obj)=>{
           let newobj= obj.cloneNode(type)
            obj.parentNode.appendChild(newobj)
        })
        return this
    }
    // 删除
    delete(){
        this.each((index,obj)=>{
            let parent=obj.parentNode
            parent.removeChild(obj)
        })
        return this
    }
    // 获取某一个父元素里面子元素的方法
    getChild(parent) {
        let childs = parent.childNodes
        let son = []
        for (let i = 0; i < childs.length; i++) {
            if (childs[i].nodeType == 1) {
                son.push(childs[i])
            }
        }
        return son
    }
    // 获得指定的所有的元素的下一个
    nexts(){
        let arr=[]
        this.each((index,obj)=>{
            arr.push(this.next(obj))
        })
        this.extand(arr,this)
        this.length=arr.length
        return this
    }
    //获得下一个元素
    next(current) {
        let next = current.nextSibling
        if (next == null) {
            return next
        }
        while (next.nodeType != 1) {
            next = next.nextSibling
            if (next == null) {
                return next
            }
        }
        return next
    }
    //获得指定元素的所有的上一个元素
    pres(){
        let arr=[]
        this.each((index,obj)=>{
            arr.push(this.pre(obj))
        })
        this.extand(arr,this)
        this.length=arr.length
        return this
    }
    //获得上一个元素
    pre(current) {
        let pre = current.previousSibling
        if (pre == null) {
            return pre
        }
        while (pre.nodeType != 1) {
            pre = pre.previousSibling
            if (pre == null) {
                return pre
            }
        }
        return pre
    }
    // 深拷贝对象
    deepextand(obj,obj1){
        let newobj=obj1||{}
        for (let i in obj){
            if (typeof  obj[i]=="object"){
                newobj[i]=this.extand(obj[i])
            }else{
            newobj[i]=obj[i]
            }
        }
        return newobj
    }
    // 浅拷贝对象

    // 追加元素的方法
    insertTo(parent){
        let parents=$(parent)
        parents.each((index,obj)=>{
            this.each((index1,obj1)=>{
                let cloneobj=obj1.cloneNode(true)
                obj.appendChild(cloneobj)
            })
        })
    }
    extand(obj,obj1){
        let newobj=obj1||{}
        for (let i in obj){
            newobj[i]=obj[i]
        }
        return newobj
    }
    toggle(){
        if(!myJquery.flag){
            this.slideUp()
            myJquery.flag=true
        }else{
            this.slideDown()
            myJquery.flag=false
        }
    }
    linear(b, c, t, d) {
        return c * t / d + b
    }
    easeIn(b, c, t, d) {
        return c * (t /= d) * t + b
    }
    easeOut(b, c, t, d) {
        return -c * (t /= d) * (t - 2) + b
    }
}

function $(selector) {
    return new myJquery(selector)
}